package io.zhengsh.redis.service.impl;

import io.zhengsh.redis.service.MultiCacheService;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.concurrent.TimeUnit;

@Service
public class RedisMultiCacheServiceImpl implements MultiCacheService {

    @Autowired
    private Redisson redisson;
    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;
    private static final String RW_LOCK_KEY = "redis.multi.cache:%s";
    private static final long CACHE_EXPIRE = 2000;

    @Override
    public String read(String key) {
        RReadWriteLock readWriteLock = redisson.getReadWriteLock(String.format(RW_LOCK_KEY, key));
        RLock rLock = readWriteLock.readLock();
        rLock.lock();
        Serializable serializable = redisTemplate.opsForValue().get(key);
        if (serializable != null) {
            // 读取的时候续期
            redisTemplate.expire(key, CACHE_EXPIRE / 3, TimeUnit.MILLISECONDS);
        }
        rLock.unlock();
        return String.valueOf(serializable);
    }

    @Override
    public String write(String key, Serializable value) {
        RReadWriteLock readWriteLock = redisson.getReadWriteLock(String.format(RW_LOCK_KEY, key));
        RLock wLock = readWriteLock.writeLock();
        wLock.lock();
        redisTemplate.opsForValue().set(key, value, CACHE_EXPIRE, TimeUnit.MILLISECONDS);
        wLock.unlock();
        return null;
    }
}
